#pragma once

#include <QtUi/ModelTest.hpp>

#include "GeneratedFiles/ui/ui_MainWindow.h"

#include "State.hpp"
#include "Project.hpp"
#include "ProjectModel.hpp"
#include "AutoCompletion.hpp"
#include "Debugger.hpp"




namespace Engine
{
	namespace Edit
	{
		namespace Ui
		{
			class MainWindow
				: public ::Ui::MainWindow
			{
			public:

				MainWindow();
				void setupUi(QMainWindow* window);



				QMenu*     menuDebug;
			};
		}
		///////////////////////////////////////////////////////////////////////////////////////////




		class MainWindow
			: public QMainWindow
		{
			Q_OBJECT

		public:

			MainWindow(QWidget* parent = nullptr);
			virtual ~MainWindow();

		public slots:

			//
			// Menu
			//

			// File
			void newProject();
			void openProject();
			void closeDocument();
			void closeProject();
			void newScript();
			void newUiDefinition();
			void save();
			void saveAll();
			void exit();

			// Debugging
			void runWithDebugger();
			void continueDebugger();
			void pauseDebugger();
			void stopDebugger();
			void debuggerStateChanged();


			//
			// Views
			//

			void documentWindowOpened(DocumentWindow* window);
			void documentWindowChanged(DocumentWindow* window);
			void documentWindowClosed(DocumentWindow* window);

			/**
			 * Updates the ui depending on the current state.
			 * Enables/Disabled actions for the most part.
			 */
			void updateUi();

		signals:

			void stateChanged(State::Type state);

		protected:

			void closeEvent(QCloseEvent* event);

		private:

			/**
			 * Changes the state of the application to the given one.
			 * Eventually emits the stateChanged signal.
			 */
			void changeState(State::Type state);

			/**
			 * Asks the user if the current project should be closed.
			 * Is only done in case there is a project and it has been modified.
			 *
			 * @returns true when the project can be closed
			 * @returns false otherwise
			 */
			bool shouldClose();

			void restoreSettings();
			void saveSettings();

			template <typename T>
			void restoreSettings(T* view)
			{
				m_settings.beginGroup(view->objectName());
				view->restoreSettings(m_settings);
				m_settings.endGroup();
			}

			template <typename T>
			void saveSettings(const T* view)
			{
				m_settings.beginGroup(view->objectName());
				view->saveSettings(m_settings);
				m_settings.endGroup();
			}

		private:

			Ui::MainWindow              ui;

			QSettings                   m_settings;

			State::Type                 m_state;

			QDir                        m_projectDir;

			Project::ptr                m_project;

			logger::memorystream::ptr   m_outputStream;
			IEngine::ptr                m_engine;


			AutoCompletion::ptr         m_autoCompletion;
			Debugger::ptr               m_debugger;
		};
		///////////////////////////////////////////////////////////////////////////////////////////
	}
	///////////////////////////////////////////////////////////////////////////////////////////////
}
///////////////////////////////////////////////////////////////////////////////////////////////////
